﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Utity;
using System.Linq;

namespace Utility
{
    public class Logger
    {
        static Logger log = null;
        public static Logger Instance {
            get {
                if (log == null) log = new Logger();
                return log;
            }
        }

        private Logger() {
             
        }

        private string logPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"Log");

        string CombinPath(string dir)
        {
            if (string.IsNullOrWhiteSpace(dir))
            {
                return logPath;
            }
       
            return Path.Combine(logPath, dir);
        }

        string PaddingChar(char c,int totalWidth)
        {
            return "".PadLeft(totalWidth,c);
        }



        string RegionStart(string title)
        {
            return "### +" + title + "  " + DateTime.Now.ToShortTimeString() + " ###\r\n";
        }

        string RegionEnd(string title)
        {
            return "### -" + title + "  结束###\r\n- - -\r\n\r\n";
        }

        string SetContent(string desc, string statement)
        {
            return  PaddingChar(' ', 4) + (!string.IsNullOrEmpty(desc) ?  desc + ":" :"") + statement + "\r\n";
        }

        private void WriteEventLog(string log, string dir )
        {
            try
            {
                string path = CombinPath(dir);
                string fileName = DateTime.Now.ToString("yyyy-MM-dd") + ".log";
                FileHelper.Instance.SaveFile(path, fileName, log);
            }
            catch
            {
            }
        }

        private string ToUrl(Dictionary<string,object> dic)
        {
            if (dic == null) return "";
              return string.Join("||",dic.Select(i=>  i.Key+"=" + i.Value.ToString()).ToList<string>());
        }

        public void WriteEventLog(string title,ParamterSet p,string dir= LoggerSubDir.normal , string LogType= LoggerType.normal)
        {
            if (string.IsNullOrEmpty(title)) {
                title = "常规操作";
            } 
            StringBuilder sb = new StringBuilder();
            sb.Append(RegionStart("[" + LogType + "]" + title));
            foreach (string key in p.GetDictionaryKeys())
            {
                sb.Append(SetContent(key,p.GetValue<string>(key)));
            }
            sb.Append(RegionEnd("[" + LogType + "]" + title));
            WriteEventLog(sb.ToString(),dir);
        }

        public void WriteEventLog(string title, string comment, string dir = LoggerSubDir.normal, string LogType = LoggerType.normal)
        {
            if (string.IsNullOrEmpty(title))
            {
                title = "常规操作";
            }
            StringBuilder sb = new StringBuilder();
            sb.Append(RegionStart("[" + LogType + "]" + title));
                sb.Append(SetContent("", comment));
            sb.Append(RegionEnd("[" + LogType + "]" + title));
            WriteEventLog(sb.ToString(), dir);
        }

        public void WriteEventLog(string title, string funcName, string paramString, Exception ex, string dir = LoggerSubDir.normal, string LogType = LoggerType.normal)
        {
            if (string.IsNullOrEmpty(title))
            {
                title = "常规操作";
            }
            StringBuilder sb = new StringBuilder();
            sb.Append(RegionStart(string.Format("[{0}{2}]{1}", LogType, title, ex!=null ? "/Exception" : "" )));
            sb.Append(SetContent("Function", funcName));
            sb.Append(SetContent("Params", paramString));
            if (ex != null)
            {
                sb.Append(SetContent("Error comment", ex.Message));
                if (!string.IsNullOrEmpty(ex.StackTrace))
                {
                    sb.Append(SetContent("Error trace", ex.StackTrace.Replace("\n", "\r\n    ")));
                }
                sb.Append(SetContent("Error C# method", ex.TargetSite.Name));
            }
            sb.Append(RegionEnd(string.Format("[{0}{2}]{1}", LogType, title, ex != null ? "/Exception" : "")));
            WriteEventLog(sb.ToString(), dir);
        }

        public void WriteEventLog(string title, string funcName, Dictionary<string, object> paramsValue, string dir = LoggerSubDir.normal, string LogType = LoggerType.normal)
        {
            WriteEventLog(title, funcName, ToUrl(paramsValue), null, dir, LogType);
        }

        public void WriteEventLog(string title, string funcName, Dictionary<string,object> paramsValue, Exception ex, string dir = LoggerSubDir.normal, string LogType = LoggerType.normal)
        {
            WriteEventLog(title, funcName, ToUrl(paramsValue),ex,dir, LogType);
        }
    }

    public static class LoggerType
    {
        public const string ect = "Ect",
                     system = "System",
                     handler = "Hanlder",
                     sql = "Sql",
                     normal = "Normal";

    }

    public static  class LoggerSubDir
    {
        public const string normal = "",
             remark = "Remark",
             cache = "Cache";
    }
}